home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Games
/
MAME
/
src
/
machine
/
sega.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-04-23
|
4KB
|
180 lines
/***************************************************************************
machine.c
Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
I/O ports)
***************************************************************************/
/*
* History:
*
* 980206 Cleaned up and simplified the spinner routines. BW
*
*/
#include "driver.h"
extern void (*sega_decrypt)(int,unsigned int *);
unsigned char *sega_mem;
unsigned char mult1;
unsigned short result;
unsigned char ioSwitch; /* determines whether we're reading the spinner or the buttons */
WRITE_HANDLER( sega_w )
{
int pc,off;
pc = cpu_getpreviouspc();
off = offset;
/* Check if this is a valid PC (ie not a spurious stack write) */
if (pc != -1)
{
int op, page;
unsigned int bad;
op = sega_mem[pc] & 0xFF;
if (op == 0x32)
{
bad = sega_mem[pc+1] & 0xFF;
page = (sega_mem[pc+2] & 0xFF) << 8;
(*sega_decrypt)(pc,&bad);
off = (page & 0xFF00) | (bad & 0x00FF);
}
}
/* MWA_ROM */
if ((off>=0x0000) && (off<=0xbfff))
{
;
}
/* MWA_RAM */
else if ((off>=0xc800) && (off<=0xefff))
{
sega_mem[off]=data;
}
}
int sega_interrupt (void)
{
if (input_port_5_r(0) & 0x01)
return nmi_interrupt();
else
return interrupt();
}
WRITE_HANDLER( sega_mult1_w )
{
mult1 = data;
}
WRITE_HANDLER( sega_mult2_w )
{
/* Curiously, the multiply is _only_ calculated by writes to this port. */
result = mult1 * data;
}
WRITE_HANDLER( sega_switch_w ) {
ioSwitch = data;
/* logerror("ioSwitch: %02x\n",ioSwitch); */
}
READ_HANDLER( sega_mult_r )
{
int c;
c = result & 0xff;
result >>= 8;
return (c);
}
/***************************************************************************
The Sega games store the DIP switches in a very mangled format that's
not directly useable by MAME. This function mangles the DIP switches
into a format that can be used.
Original format:
Port 0 - 2-4, 2-8, 1-4, 1-8
Port 1 - 2-3, 2-7, 1-3, 1-7
Port 2 - 2-2, 2-6, 1-2, 1-6
Port 3 - 2-1, 2-5, 1-1, 1-5
MAME format:
Port 6 - 1-1, 1-2, 1-3, 1-4, 1-5, 1-6, 1-7, 1-8
Port 7 - 2-1, 2-2, 2-3, 2-4, 2-5, 2-6, 2-7, 2-8
***************************************************************************/
READ_HANDLER( sega_ports_r )
{
int dip1, dip2;
dip1 = input_port_6_r(offset);
dip2 = input_port_7_r(offset);
switch(offset)
{
case 0:
return ((input_port_0_r(0) & 0xF0) | ((dip2 & 0x08)>>3) |
((dip2 & 0x80)>>6) | ((dip1 & 0x08)>>1) | ((dip1 & 0x80)>>4));
case 1:
return ((input_port_1_r(0) & 0xF0) | ((dip2 & 0x04)>>2) |
((dip2 & 0x40)>>5) | ((dip1 & 0x04)>>0) | ((dip1 & 0x40)>>3));
case 2:
return ((input_port_2_r(0) & 0xF0) | ((dip2 & 0x02)>>1) |
((dip2 & 0x20)>>4) | ((dip1 & 0x02)<<1) | ((dip1 & 0x20)>>2));
case 3:
return ((input_port_3_r(0) & 0xF0) | ((dip2 & 0x01)>>0) |
((dip2 & 0x10)>>3) | ((dip1 & 0x01)<<2) | ((dip1 & 0x10)>>1));
}
return 0;
}
READ_HANDLER( sega_IN4_r ) {
/*
* The values returned are always increasing. That is, regardless of whether
* you turn the spinner left or right, the self-test should always show the
* number as increasing. The direction is only reflected in the least
* significant bit.
*/
int delta;
static int sign;
static int spinner;
if (ioSwitch & 1) /* ioSwitch = 0x01 or 0xff */
return readinputport (4);
/* else ioSwitch = 0xfe */
/* I'm sure this can be further simplified ;-) BW */
delta = readinputport(8);
if (delta != 0)
{
sign = delta >> 7;
if (sign)
delta = 0x80-delta;
spinner += delta;
}
return (~((spinner<<1) | sign));
}
READ_HANDLER( elim4_IN4_r )
{
/* If the ioPort ($f8) is 0x1f, we're reading the 4 coin inputs. */
/* If the ioPort ($f8) is 0x1e, we're reading player 3 & 4 controls.*/
if (ioSwitch == 0x1e)
return readinputport (4);
if (ioSwitch == 0x1f)
return readinputport (8);
return (0);
}